﻿namespace DYH.Extensions.CAD.Tools;

/// <summary>
/// 表示一个可释放的动作集合，用于在对象被释放时执行一系列动作。
/// </summary>
public sealed class DisposeAction : IDisposable
{
    /// <summary>
    /// 创建一个包含指定动作的DisposeAction实例。
    /// </summary>
    /// <param name="action">需要添加到DisposeAction中的动作。</param>
    /// <returns>返回一个包含指定动作的DisposeAction实例。</returns>
    public static DisposeAction Action(Action action)
    {
        DisposeAction da = new();
        da.Add(action);
        return da;
    }

    private readonly Queue<Action> _actionQueue = new Queue<Action>();

    /// <summary>
    /// 将指定的动作添加到当前DisposeAction的动作队列中。
    /// </summary>
    /// <param name="action">需要添加的动作。</param>
    public void Add(Action action)
    {
        _actionQueue.Enqueue(action);
    }

    private bool _disposedValue;

    /// <summary>
    /// 执行释放操作，根据是否显式释放来决定是否执行托管资源的清理。
    /// </summary>
    /// <param name="disposing">指示是否显式释放托管资源。</param>
    private void Dispose(bool disposing)
    {
        if (_disposedValue)
            return;

        if (disposing)
        {
            // 遍历并执行所有已注册的动作
            while (_actionQueue.Count != 0)
            {
                _actionQueue.Dequeue().Invoke();
            }
        }

        // 设置已释放标志为true，避免重复释放
        _disposedValue = true;
    }

    /// <summary>
    /// 析构函数，确保在垃圾回收时调用释放逻辑。
    /// </summary>
    ~DisposeAction()
    {
        // 调用Dispose方法，传入false表示不释放托管资源
        Dispose(disposing: false);
    }

    /// <summary>
    /// 执行与释放或重置非托管资源相关的应用程序定义的任务。
    /// </summary>
    public void Dispose()
    {
        // 调用Dispose方法，传入true表示释放托管资源
        Dispose(disposing: true);

        // 抑制终结器，避免重复调用析构函数
        GC.SuppressFinalize(this);
    }
}
